<template>
  <!-- 用户表单 -->
  <el-drawer
    v-model="dialog.visible"
    :title="dialog.title"
    append-to-body
    size="80%"
    @close="handleCloseDialog"
  >
    <div class="icons-container">
      <el-tabs type="border-card">
        <el-tab-pane label="图形">
          <div class="grid" style="width: 100%; height: 680px">
            <div ref="chartRef" style="width: 100%; height: 680px"></div>
            <button class="layout-switch-button" @click="switchLayout">切换布局</button>
          </div>
        </el-tab-pane>
        <el-tab-pane label="列表">
          <div class="grid">
            <el-table :data="tableData" border style="width: 100%">
              <el-table-column
                v-for="column in columns"
                :key="column.prop"
                :prop="column.prop"
                :label="column.label"
                :width="column.width"
                align="center"
              >
                <template #default="{ row }">
                  {{ row[column.prop] }}
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-tab-pane>
        <el-tab-pane label="关联分析">
          <div>
            <div v-if="resultApriori" class="results">
              <div class="section">
                <h2>中药饮片频数统计</h2>
                <ul>
                  <li v-for="(support, itemset) in resultApriori.frequentItemsets" :key="itemset">
                    {{ itemset }} → Support: {{ support }}
                  </li>
                </ul>
              </div>

              <div class="section">
                <h2>中药饮片关联度分析</h2>
                <ul>
                  <li v-for="(confidence, rule) in resultApriori.associationRules" :key="rule">
                    {{ rule }} → Confidence: {{ confidence.toFixed(2) }}
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCloseDialog">取 消</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import * as echarts from "echarts";
import { reactive, ref, nextTick } from "vue";
import Neo4jAPI, { Disease } from "@/api/neo4j/diseases";
import TopicTcmAPI, {
  TopicTcmPageVO,
  TopicTcmForm,
  TopicTcmPageQuery,
  AprioriVO,
} from "@/api/project/topic-tcm";

const loading = ref(false);
const diseases = ref<{ id: number; name: string }[]>([]);
const chartRef = ref<HTMLElement | null>(null);
const chartInstance = ref<echarts.ECharts | null>(null); // 用于存储 ECharts 实例
const currentLayout = ref<"force" | "circular">("force"); // 当前布局类型
// 表格列
const columns = ref<{ prop: string; label: string }[]>([]);
// 表格数据
const tableData = ref<Record<string, string>[]>([]);

// 弹窗
const dialog = reactive({
  title: "",
  visible: false,
});

/** 关闭处方组成弹窗 */
function handleCloseDialog() {
  dialog.visible = false;
}

// 渲染图表
const renderChart = (data: Disease[]) => {
  if (!chartRef.value) {
    console.error("Chart container is not initialized.");
    return;
  }

  // 如果 ECharts 实例不存在，则初始化
  if (!chartInstance.value) {
    chartInstance.value = echarts.init(chartRef.value);
  }

  // 处理节点和关系
  const nodes = data.flatMap((disease) => [
    {
      id: `disease-${disease.id}`, // 使用疾病ID作为唯一标识
      name: disease.name,
      category: "处方",
      symbolSize: 60,
      itemStyle: {
        color: "red", // 疾病节点背景色为红色
      },
      label: {
        show: true,
        color: "white", // 疾病节点文字颜色为白色
        fontSize: 14,
      },
    },
    ...disease.drugs.map((drug) => ({
      id: `drug-${drug.drug.name}`, // 使用药品名称作为唯一标识
      name: drug.drug.name,
      category: "药味",
      symbolSize: 60, // 设置节点大小
      label: {
        show: true,
        color: "white", // 药品节点文字颜色为白色
        fontSize: 12,
      },
    })),
  ]);

  // 去重：确保节点ID唯一
  const nodeMap = new Map();
  nodes.forEach((node) => {
    if (!nodeMap.has(node.id)) {
      nodeMap.set(node.id, node);
    }
  });
  const uniqueNodes = Array.from(nodeMap.values());

  // 处理关系
  const links = data.flatMap((disease) =>
    disease.drugs.map((drug) => ({
      source: `disease-${disease.id}`, // 使用疾病ID作为源节点
      target: `drug-${drug.drug.name}`, // 使用药品名称作为目标节点
      name: drug.type, // 关系类型
      label: {
        show: false, // 显示关系标签
        color: "white", // 设置字体颜色
        fontSize: 12, // 设置字体大小
        // backgroundColor: "#fff", // 设置字体背景色
        // padding: [2, 4], // 设置内边距
        // borderRadius: 3, // 设置圆角
      },
    }))
  );

  const option = {
    title: {
      text: "处方药味图谱",
      // subtext: "xxxx",
      top: "top",
      left: "left",
    },
    tooltip: {},
    legend: {
      data: ["处方", "药味"], // 使用中文
      // selectedMode: "multiple", // 允许点击图例隐藏/显示数据系列
    },
    animationDurationUpdate: 1500,

    series: [
      {
        type: "graph",
        //layout: "force",
        layout: currentLayout.value,
        symbolSize: 50,
        roam: true,
        data: uniqueNodes,
        links: links,
        categories: [
          { name: "处方", itemStyle: { color: "red" } }, // 疾病节点颜色为红色
          { name: "药味", itemStyle: { color: "blue" } }, // 药品节点颜色为蓝色
        ],

        label: {
          normal: {
            show: true,
            color: "white", // 疾病节点文字颜色为白色
            textStyle: {},
          },
        },
        edgeSymbol: ["circle", "arrow"],
        edgeSymbolSize: [4, 10],
        edgeLabel: {
          fontSize: 12,
          show: true,
        },
        force: {
          repulsion: 1000, // 调整节点之间的斥力
          edgeLength: [50, 200], // 边的长度范围
          gravity: 0.1, // 引力系数
        },
        draggable: true,
      },
    ],
  };

  // 设置图表配置
  chartInstance.value.setOption(option);

  // 监听 Legend 点击事件  vue3 点击图标不能自动去掉连接线
  chartInstance.value.on("legendselectchanged", (params: any) => {
    const selected = params.selected;
    const updatedNodes = uniqueNodes.filter((node) => selected[node.category]);
    const updatedLinks = links.filter(
      (link) =>
        selected[uniqueNodes.find((node) => node.id === link.source)?.category] &&
        selected[uniqueNodes.find((node) => node.id === link.target)?.category]
    );

    // 更新图表
    chartInstance.value?.setOption({
      series: [
        {
          data: updatedNodes,
          links: updatedLinks,
        },
      ],
    });
  });
};

// 处理数据
const processData = (data: Disease[]) => {
  debugger;
  // 1. 获取所有药品名称
  const allDrugs = new Set<string>();
  const transList = new Set<string>();
  data.forEach((disease) => {
    let drugsList = new Set<string>();
    disease.drugs.forEach((drug) => {
      allDrugs.add(drug.drug.name);
      drugsList.add(drug.drug.name);
    });
    // 将drugsList 转成 字符串
    transList.add(Array.from(drugsList).join(","));
  });

  // 2. 动态生成列
  columns.value = [
    { prop: "drug", label: "药味\\处方", width: 100 }, // 第一列：药品名称
    ...data.map((disease) => ({
      prop: disease.name, // 列名：疾病名称
      label: disease.name, // 列标题：疾病名称
      width: 100,
    })),
  ];

  // 3. 动态生成表格数据
  tableData.value = Array.from(allDrugs).map((drug) => {
    const row: Record<string, string> = { drug }; // 第一列：药品名称
    data.forEach((disease) => {
      // 检查药品是否存在于当前疾病中
      const hasDrug = disease.drugs.some((d) => d.drug.name === drug);
      row[disease.name] = hasDrug ? "Y" : ""; // 如果存在，标记为 Y；否则为空
    });
    return row;
  });

  // 4. 渲染图表
  if (transList.size > 0) {
    getAprioriData(Array.from(transList)); // 将 Set<string> 转换为 string[]
  }
};

const data = ref<Disease[]>([]);
// 获取所有疾病
const fetchDiseases = async (ids_str: string) => {
  // const ids: number[] = [1, 2, 3];
  const ids: number[] = ids_str.split(",").map((id) => parseInt(id));
  try {
    loading.value = true;
    data.value = await Neo4jAPI.getDiseasesByIds(ids);
    console.log("Fetched data:", data); // 打印数据，确保格式正确
    renderChart(data.value);
    // 处理数据
    processData(data.value);
  } catch (error) {
    console.error("获取疾病列表失败:", error);
  } finally {
    loading.value = false;
  }
};

const resultApriori = ref<AprioriVO | null>(null);
function getAprioriData(transList: string[]) {
  loading.value = true;
  TopicTcmAPI.getApriori(transList)
    .then((data) => {
      resultApriori.value = data;
    })
    .finally(() => {
      loading.value = false;
    });
}

// 切换布局
const switchLayout = () => {
  currentLayout.value = currentLayout.value === "force" ? "circular" : "force";
  renderChart(data.value); // 重新渲染图表
};

const openDialog = async (ids: string) => {
  dialog.title = "查看详情";
  dialog.visible = true;

  // 确保 DOM 完全渲染后再初始化图表
  nextTick(() => {
    fetchDiseases(ids);
  });
};

defineExpose({
  openDialog,
});
</script>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  position: relative;
}

.chart-container {
  width: 100%;
  height: 100%;
}

.layout-switch-button {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1000; /* 确保按钮在图表上方 */
  padding: 8px 16px;
  font-size: 14px;
  color: #fff;
  background-color: #007bff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.layout-switch-button:hover {
  background-color: #0056b3;
}
/* 
ul {
  list-style-type: none;
  padding: 0;
}

li {
  padding: 8px;
  border-bottom: 1px solid #eee;
}

li:last-child {
  border-bottom: none;
} */
</style>
